﻿@implements IDisposable
@inject NavigationManager Navigation

<nav aria-label="breadcrumb">
  <ol class="breadcrumb m-0">
    <li class="breadcrumb-item"><a href="/"><i class="fa fa-tachometer" aria-hidden="true"></i></a></li>   
    @foreach (var node in Nodes)
    {
        @if (node.Items.Any())
        {
            <li class="breadcrumb-item cascade menu dropdown">
                 <a class="dropdown-toggle" href="#" role="button" id="@node.Id" data-bs-toggle="dropdown" aria-expanded="false">
                    @node.Text
                  </a>

                <div class="dropdown-menu" aria-labelledby="@node.Id">
                    @foreach(var item in node.Items)
                    {
                        @if (item.Items.Any())
                        {
                            <div class="has-leaf dropdown-item">
                                <span>@item.Text</span>
                                <i class="fa fa-angle-down nav-link-right"></i>
                                @RenderSubNav(item.Items)
                            </div>
                        }
                        else
                        {
                            <a class="dropdown-item" href="@(item.Url??"#")">@item.Text</a>         
                        }
                    }
                </div>
                <div class="dropdown-menu-arrow mt-1"></div>
            </li>
        }
        else
        {
            <li class="breadcrumb-item active" aria-current="page">@node.Text</li>            
        }
    }
  </ol>
</nav>

@code {

    /// <summary>
    /// 当前会话状态
    /// </summary>
    [CascadingParameter]
    public SessionState State { get; set; } = new();

    /// <summary>
    /// 当前面包屑菜单
    /// </summary>
    private Stack<MenuItem> Nodes { get; set; } = new();

    /// <summary>
    /// OnInitialized
    /// </summary>
    protected override void OnInitialized() => Navigation.LocationChanged += HandleLocationChanged;

    /// <summary>
    /// 根据菜单Url递归查找
    /// </summary>
    /// <param name="menus">菜单</param>
    /// <param name="location">目标菜单Id</param>
    /// <returns></returns>
    private bool RecursionTreeNodes(IEnumerable<MenuItem> menus, string location)
    {
        foreach (var item in menus)
        {
            if (item.Items.Any())
            {
                if (RecursionTreeNodes(item.Items, location))
                {
                    Nodes.Push(item);
                }
            }
            else if (!string.IsNullOrWhiteSpace(item.Url))
            {
                if (item.Url.TrimStart('/').Equals(location, StringComparison.OrdinalIgnoreCase))
                {
                    Nodes.Push(item);
                    return true;
                }
            }
        }
        return false;
    }

    /// <summary>
    /// 页面加载完成
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void HandleLocationChanged(object? sender, LocationChangedEventArgs e)
    {
        Nodes.Clear();

        var location = Navigation.ToBaseRelativePath(e.Location);

        if (string.IsNullOrWhiteSpace(location))
        {
            StateHasChanged();
            return;
        }

        RecursionTreeNodes(State.Menus, location);

        if (Nodes.Count > 0)
        {
            StateHasChanged();
        }
    }

    /// <summary>
    /// Dispose
    /// </summary>
    public void Dispose() => Navigation.LocationChanged -= HandleLocationChanged;

    /// <summary>
    /// 渲染面包屑
    /// </summary>
    RenderFragment<IEnumerable<MenuItem>> RenderSubNav => menus => 
    @<ul class="nav sub-menu">
        @foreach(var menu in menus)
        {
            @if (menu.Items.Any())
            {
                <li>
                    <div class="has-leaf nav-link">
                        <span>@menu.Text</span>
                        <i class="fa fa-angle-down nav-link-right"></i>
                        @RenderSubNav(menu.Items)
                    </div>
                </li>      
            }
            else
            {
                <li><a class="nav-link" href="@(menu.Url??"#")">@menu.Text</a></li>                
            }
        }
    </ul>;
}
